/*
ont-space - The ontology-based resource metadata repository
Copyright (c) 2006-2008, Information Eng. Research Unit - Univ. of Alcalá
http://www.cc.uah.es/ie
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at your option)
any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package org.ontspace.util.translator.lom2owl.owl;

import org.ieee.ltsc.lom.LOM;
import org.ieee.ltsc.lom.LOMUtil;

import java.io.*;
import com.hp.hpl.jena.ontology.*;
import com.hp.hpl.jena.rdf.model.RDFNode;

import org.ieee.ltsc.lom.LOM.LifeCycle.Contribute.Entity;
import org.ietf.mimedir.vcard.*;

/**
 * 
 * Translates a LOM contribution element to its representation in OWL. 
 */
public class C2CTranslator extends ElementTranslatorImpl {

    private String category =
            new String();
    private String attributeName =
            new String();
    private String element =
            new String();

    private enum CAMPOS {

        FN, N, EMAIL, ORG, OTRO
    }

    /** Creates a new instance of C2CTranslator */
    public C2CTranslator(String elementCategory, String elementElement,
            String elementAttribute) {

        category =
                elementCategory;
        attributeName =
                elementAttribute;
        element =
                elementElement;
    }

    /**    
     * This method translates a LOM contribution element to its representation
     * in OWL
     * @param lom The metadata record
     * @param ont The ontology
     * @param inst The instance of learning Object
     * @param nsName The namespace
     * @param errorWriter The error file
     */
    public void apply(LOM lom, OntModel ont, Individual inst, String nsName,
            PrintWriter errorWriter) {

        OntClass lomContributionClass =
                ont.getOntClass(nsName +
                "#learningObjectContribution");
        OntClass langStringClass =
                ont.getOntClass(nsName + "#langString");
        OntClass singleLangStringClass =
                ont.getOntClass(nsName +
                "#singleLangString");
        OntClass VCardClass =
                ont.getOntClass(nsName + "#vCard");
        OntClass dateTimeClass =
                ont.getOntClass(nsName + "#lomDateTime");

        DatatypeProperty roleProperty =
                ont.getDatatypeProperty(nsName +
                "#hasLearningObjectContributionRole");
        DatatypeProperty emailProperty =
                ont.getDatatypeProperty(nsName +
                "#hasEmail");
        DatatypeProperty nameProperty =
                ont.getDatatypeProperty(nsName +
                "#hasName");
        DatatypeProperty fNameProperty =
                ont.getDatatypeProperty(nsName +
                "#hasFName");
        DatatypeProperty organizationProperty =
                ont.getDatatypeProperty(nsName +
                "#hasOrganization");
        DatatypeProperty hasValueProperty =
                ont.getDatatypeProperty(nsName +
                "#hasValue");
        DatatypeProperty inLanguageProperty =
                ont.getDatatypeProperty(nsName +
                "#inLanguage");
        DatatypeProperty dateTimeProperty =
                ont.getDatatypeProperty(nsName +
                "#hasDateTimeValue");

        ObjectProperty contributeProperty =
                ont.getObjectProperty(nsName +
                "#hasContribution");
        ObjectProperty contributingProperty =
                ont.getObjectProperty(nsName +
                "#contributingEntity");
        ObjectProperty includeLangStringProperty =
                ont.getObjectProperty(nsName + "#includesSingleLangString");
        ObjectProperty contributionDateTimeProperty =
                ont.getObjectProperty(nsName + "#contributionDateTime");
        ObjectProperty descriptionProperty =
                ont.getObjectProperty(nsName +
                "#hasDateTimeDescription");

        String instance =
                null;

        int i =
                0;
        while (LOMUtil.getLifeCycleContribute(lom, i) != null) {

            instance =
                    "#LCC" +
                    inst.getLocalName().substring(3) + "-" + String.valueOf(i);

            Individual instanceContribution =
                    ont.createIndividual(nsName +
                    instance, lomContributionClass);

            //2.3.1 role         
            String roleLOM =
                    LOMUtil.getValue(LOMUtil.getLifeCycleContributeRole(lom, i));
            if (roleLOM != null) {
                RDFNode roleValue =
                        ont.createTypedLiteral(roleLOM);
                instanceContribution.setPropertyValue(roleProperty, roleValue);
            }

            //2.3.2 entity                  

            int j =
                    0;
            while (LOMUtil.getLifeCycleContributeEntity(lom, i, j) != null) {
                instance =
                        "#LCvCard" +
                        inst.getLocalName().substring(3) + "-" +
                        String.valueOf(j);

                Individual instanceVCard =
                        ont.createIndividual(nsName +
                        instance, VCardClass);

                Entity ent =
                        LOMUtil.getLifeCycleContributeEntity(lom, i, j);
                VCard MimeDirImpl2 =
                        ent.vcard();


                CAMPOS campo =
                        null;

                int lines =
                        MimeDirImpl2.getContentLineCount();

                for (int contador =
                        0; contador < lines; contador++) {

                    String value =
                            MimeDirImpl2.getContentLine(contador).
                            getValueType().
                            toString();

                    if (value.contains("FN:")) {
                        campo =
                                CAMPOS.FN;
                    } else if ((value.contains("N:")) &&
                            !(value.contains("VERSION:"))) {
                        campo =
                                CAMPOS.N;
                    } else if (value.contains("EMAIL:")) {
                        campo =
                                CAMPOS.EMAIL;
                    } else if (value.contains("ORG:")) {
                        campo =
                                CAMPOS.ORG;
                    } else {
                        campo =
                                CAMPOS.OTRO;
                    }

                    switch (campo) {
                        case N:  //Name

                            try {
                                String nameLOM =
                                        value;
                                if (nameLOM != null) {
                                    RDFNode nameValue =
                                            ont.createTypedLiteral(nameLOM);
                                    instanceVCard.setPropertyValue(nameProperty,
                                            nameValue);
                                //System.out.println("N: "+value);
                                }
                            } catch (Exception e) {
                                String log =
                                        "The name field of the Annotation category must contain a value";
                                errorWriter.println(log + '\n' + e);
                            }

                            break;

                        case FN:  //FName

                            try {
                                String fNameLOM =
                                        value;
                                if (fNameLOM != null) {
                                    RDFNode fNameValue =
                                            ont.createTypedLiteral(fNameLOM);
                                    instanceVCard.setPropertyValue(fNameProperty,
                                            fNameValue);
                                //System.out.println("FN: "+value);
                                }
                            } catch (Exception e) {
                                String log =
                                        "The name field of the Annotation category must contain a value";
                                errorWriter.println(log + '\n' + e);
                            }
                            break;


                        case EMAIL:  //Email


                            try {
                                String emailLOM =
                                        value;
                                if (emailLOM != null) {
                                    RDFNode emailValue =
                                            ont.createTypedLiteral(emailLOM);
                                    instanceVCard.setPropertyValue(emailProperty,
                                            emailValue);
                                //System.out.println("EMAIL: "+value);
                                }
                            } catch (Exception e) {
                                String log =
                                        "The Email field of the Annotation category must contain a value";
                                errorWriter.println(log + '\n' + e);
                            }

                            break;

                        case ORG:  //Organization

                            try {
                                String organizationLOM =
                                        value;
                                if (organizationLOM != null) {
                                    RDFNode organizationValue =
                                            ont.createTypedLiteral(organizationLOM);
                                    instanceVCard.setPropertyValue(organizationProperty,
                                            organizationValue);
                                //System.out.println("ORG: "+value);
                                }
                            } catch (Exception e) {
                                String log =
                                        "The Organization field of the Annotation category must contain a value";
                                errorWriter.println(log + '\n' + e);
                            }
                            break;

                        case OTRO:
                            break;


                    }
                }


                instanceContribution.addProperty(contributingProperty,
                        instanceVCard);
                j++;

            }
            inst.setPropertyValue(contributeProperty, instanceContribution);

            //2.3.3 date time              
            Individual instanceDateTime =
                    null;

            try {
                String valueLOM =
                        LOMUtil.getString(LOMUtil.getLifeCycleContributeDate(lom,
                        i).
                        value());
                if (valueLOM != null) {
                    instance =
                            "#LCdate" + inst.getLocalName().substring(3) + "-" +
                            String.valueOf(i);

                    instanceDateTime =
                            ont.createIndividual(nsName + instance,
                            dateTimeClass);

                    RDFNode dateValue =
                            ont.createTypedLiteral(valueLOM);
                    instanceDateTime.setPropertyValue(dateTimeProperty,
                            dateValue);
                }
            } catch (Exception e) {
            }

            //description date time                                   
            try {
                if (LOMUtil.getLifeCycleContributeDate(lom, i).description() !=
                        null) {
                    instance =
                            "#lsDate" + inst.getLocalName().substring(3) + "-" +
                            String.valueOf(i);

                    Individual langInstance =
                            ont.createIndividual(nsName +
                            instance, langStringClass);
                    j =
                            0;
                    while (LOMUtil.getString(LOMUtil.getLifeCycleContributeDate(lom,
                            i).description(), j) != null) {
                        instance =
                                "#slsDate" + inst.getLocalName().substring(3) +
                                "-" + String.valueOf(j);

                        Individual singleInstance =
                                ont.createIndividual(nsName + instance,
                                singleLangStringClass);
                        String descriptionLOM =
                                LOMUtil.getString(LOMUtil.getLifeCycleContributeDate(lom,
                                i).
                                description(), j);
                        String languageLOM =
                                LOMUtil.getLanguage(LOMUtil.getLifeCycleContributeDate(lom,
                                i).
                                description(), j);

                        if (descriptionLOM != null) {
                            RDFNode descriptionValue =
                                    ont.createTypedLiteral(descriptionLOM);
                            singleInstance.setPropertyValue(hasValueProperty,
                                    descriptionValue);
                        } else {
                            String log =
                                    "The Description field of DateDescription in the lifeCycle category must contain a value";
                            errorWriter.println(log);
                        }
                        if (languageLOM != null) {
                            RDFNode languageValue =
                                    ont.createTypedLiteral(languageLOM);
                            singleInstance.setPropertyValue(inLanguageProperty,
                                    languageValue);
                        } else {
                            String log =
                                    "The Language field of DateDescription in the lifeCycle category must contain a value";
                            errorWriter.println(log);
                        }
                        langInstance.addProperty(includeLangStringProperty,
                                singleInstance);
                        j++;
                    }
                    instanceDateTime.setPropertyValue(descriptionProperty,
                            langInstance);
                }
            } catch (Exception e) {
            }

            instanceContribution.setPropertyValue(contributionDateTimeProperty,
                    instanceDateTime);

            i++;

        }


    }
}
